﻿using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;

namespace GameLogic.Dev
{
    public class PathHelper
    {
        public static double GetPathLength(Path path)
        {
            double result = 0.0;

            Point? _lastPoint = null;
            PathGeometry pathGeometry = path.Data as PathGeometry;
            foreach (var pf in pathGeometry.Figures)
            {
                foreach (var ps in pf.Segments)
                {
                    PolyLineSegment pls = ps as PolyLineSegment;

                    foreach(var p in pls.Points)
                    {
                        if (_lastPoint != null)
                        {
                            // Calc diff between p1 and p2
                            double diff = Distance2D(p, _lastPoint.Value);
                            result += diff;
                        }
                        _lastPoint = p;
                    }
                }
            }
            return result;
        }

        public static ExtendedPoint GetPosition(Path path, double length)
        {
            double diffSum = 0.0;
            ExtendedPoint result = new ExtendedPoint();

            Point? _lastPoint = null;
            PathGeometry pathGeometry = path.Data as PathGeometry;
            foreach (var pf in pathGeometry.Figures)
            {
                foreach (var ps in pf.Segments)
                {
                    PolyLineSegment pls = ps as PolyLineSegment;

                    foreach (var p in pls.Points)
                    {
                        if (_lastPoint != null)
                        {
                            // Calc diff between p1 and p2
                            double diff = Distance2D(p, _lastPoint.Value);
                            diffSum += diff;

                            if (diffSum > length)
                            {
                                // ~ value
                                result.Point = p;
                                result.Angle = Angle(p, _lastPoint.Value);
                                return result;
                            }
                        }
                        _lastPoint = p;
                    }
                }
            }
            return null;
        }

        public static double Distance2D(Point p1, Point p2)
        {
            return Distance2D(p1.X, p1.Y, p2.X, p2.Y);
        }

        private static double Distance2D(double x1, double y1, double x2, double y2)
        {
            double result = 0;
            double part1 = Math.Pow((x2 - x1), 2);
            double part2 = Math.Pow((y2 - y1), 2);
            double underRadical = part1 + part2;
            result = Math.Sqrt(underRadical);
            
            return result;
        }

        private static double Angle(Point p1, Point p2)
        {
            return Angle(p1.X, p1.Y, p2.X, p2.Y);
        }

        private static double Angle(double px1, double py1, double px2, double py2)
        {
            // Negate X and Y values 
            double difX = px2 - px1; 
            double difY = py2 - py1;
            
            double angle = 0.0; // Calculate the angle 
            if (difX == 0.0)
            {
                if (difX == 0.0)
                {
                    angle = 0.0;
                }
                else if (difY > 0.0)
                {
                    angle = System.Math.PI / 2.0;
                }
                else
                {
                    angle = System.Math.PI * 3.0 / 2.0;
                }
            }
            else if (difY == 0.0)
            {
                if (difX > 0.0)
                {
                    angle = 0.0;
                }
                else
                {
                    angle = System.Math.PI;
                }
            }
            else
            {
                if (difX < 0.0)
                {
                    angle = System.Math.Atan(difY / difX) + System.Math.PI;
                }
                else if (difY < 0.0)
                {
                    angle = System.Math.Atan(difY / difX) + (2 * System.Math.PI);
                }
                else
                {
                    angle = System.Math.Atan(difY / difX);
                }
            }

            // Convert to degrees 
            angle = angle * 180 / System.Math.PI;
            angle -= 90.0;

            return angle;
        }
    }

    public class ExtendedPoint
    {
        public Point Point { get; set; }
        public double Angle { get; set; }
        public double X
        {
            get
            {
                if (Point != null)
                {
                    return Point.X;
                }
                else
                {
                    return 0;
                }
            }
        }
        public double Y
        {
            get
            {
                if (Point != null)
                {
                    return Point.Y;
                }
                else
                {
                    return 0;
                }
            }
        }
    }
}
